﻿using System;
using TestingConcurrencyBenchmark.Helpers;

namespace TestingConcurrencyBenchmark.Problems.ProducerConsumer
{
    /// <summary>
    /// An abstraction of the Producer Consumer problem
    /// A producer must place an action onto an actionqueue
    /// A consumer must remove the action from the actionqueue
    /// A producer must have the means to signal to the consumer an item has been placed on the actionqueue
    /// 
    /// To this end 2 methods have been implemented: Consume and Produce
    /// A buffer has been provided
    /// An Items Semaphore has been provided
    /// 
    /// All implementations have access to these
    /// </summary>
    public abstract class AbstractProducerConsumer
    {
        protected AbstractProducerConsumer()
        {
            Items = new BenchmarkSemaphore(0);
            Buffer = new ActionQueue();
        }

        /// <summary>
        /// An actionQueue, all actions produced will have to be put onto this queue
        /// </summary>
        public ActionQueue Buffer { get; protected set; }

        /// <summary>
        /// A way for a producer to indicate to the consumer an item has been produced
        /// </summary>
        protected BenchmarkSemaphore Items { get; private set; }

        /// <summary>
        /// Method for consumers, an action will have to be taken off of the actionQueue
        /// </summary>
        public abstract void Consume();

        /// <summary>
        /// Method for producers, an action will have to be placed onto the actionQueue
        /// </summary>
        /// <param name="action">the action to be placed onto the actionQueue</param>
        public abstract void Produce(Action action);
    }
}